package com.software.sqlite.utils;


import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Author: wulihua
 * @Date: 2019/4/18 17:01
 */
public class CommonUtils {
    /**
     * email 正确的书写格式为 username@domain
     */
    public static String strEmail = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
    /**
     * 电话 正确格式 012-87654321、0123-87654321、0123－7654321
     */
    public static String strTel = "\\d{4}-\\d{8}|\\d{4}-\\d{7}|\\d(3)-\\d(8)";
    /**
     * 手机号码 13187654321 13587654321
     */
    public static String strPhone = "^((17[0-9])|(16[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9])|(19[0,5-9]))\\d{8}$";
    /**
     * 汉字 中国
     */
    public static String strChinese = "^[\u4e00-\u9fa5]+$";
    /**
     * IP 192.168.1.1
     */
    public static String strIp = "\\d{1,3}+\\.\\d{1,3}+\\.\\d{1,3}+\\.\\d{1,3}";
    /**
     * QQ 456789
     */
    public static String strQQ = "[1-9][0-9]{4,13}";
    /**
     * 邮编 210000
     */
    public static String strMail = "[1-9]\\d{5}(?!\\d)";
    /**
     * 身份证号码 15或者18位
     */
    public static String strId = "\\d{15}|\\d{18}";

    /**
     * 时间分割长度
     */
    private static int TIME_SPLIT_LENGTH = 3;

    /**
     * 手机号正则
     */
    private static String MOBILE_MATCHE = "\\d{11}";

    public static String POLAR_MATCHE="^[A-Z0-9]{8}";

    /**
     * 分秒时间分割
     */
    private static String MINUTE_SPLIT = ".";

    /**
     * 时间进制
     */
    private static int TIME_UNIT_BASE = 60;

    /**
     * 整数进制
     */
    private static int INT_UNIT_BASE = 60;

    private static String SECOND_UNIT = "″";

    private static String MINUTE_UNIT = "′";

    private static String HOUR_UNIT = "°";

    public static String uuid(){
        return UUID.randomUUID().toString().replaceAll("-","").toLowerCase();
    }

    public static String getTimeFromInt(int time) {
        if (time <= 0) {
            return "00:00:000";
        }
        // 初始化Formatter的转换格式
        SimpleDateFormat formatter = new SimpleDateFormat("mm:ss:SSS");
        String hms = formatter.format(time);
        return hms;
    }

    public static int getTimeFromStr(String str) {
        int result = 0;
        if (CommonUtils.isNotBlank(str)) {
            String[] timeArray = str.split(":");
            if (timeArray.length == TIME_SPLIT_LENGTH) {
                int mm = CommonUtils.parseIntegerData(timeArray[0]) * 60 * 1000;
                int ss = CommonUtils.parseIntegerData(timeArray[1]) * 1000;
                int sss = CommonUtils.parseIntegerData(timeArray[2]);
                result = mm + ss + sss;
            }
        }
        return result;
    }

    public static double getTimeSecondFromStr(String str) {
        double result = 0;
        if (CommonUtils.isNotBlank(str)) {
            String[] timeArray = str.split(":");
            if (timeArray.length == TIME_SPLIT_LENGTH) {
                int mm = CommonUtils.parseIntegerData(timeArray[0]) * 60;
                int ss = CommonUtils.parseIntegerData(timeArray[1]);
                int sss = CommonUtils.parseIntegerData(timeArray[2]);
                result = CommonUtils.parseDoubleData((mm + ss) + "." + sss);
            }
        }
        return result;
    }

    public static boolean isBlank(String str) {
        boolean result = false;
        if (StringUtils.isBlank(str)) {
            result = true;
        }
        return result;
    }

    public static boolean isNotBlank(String str) {
        boolean result = false;
        if (StringUtils.isNotBlank(str)) {
            result = true;
        }
        return result;
    }

    public static boolean isEmpty(String str) {
        boolean result = false;
        if (StringUtils.isEmpty(str)) {
            result = true;
        }
        return result;
    }

    public static boolean isNotEmpty(String str) {
        boolean result = false;
        if (StringUtils.isNotEmpty(str)) {
            result = true;
        }
        return result;
    }

    /**
     * false 需要更新版本 true 不需要更新版本
     *
     * @param currentVersion
     * @param serverVersion
     * @return
     */
    public static boolean compareVersion(String currentVersion, String serverVersion) {
        if (currentVersion.equals(serverVersion)) {
            return false;
        }
        String[] version1Array = serverVersion.split("\\.");
        String[] version2Array = currentVersion.split("\\.");
        int index = 0;
        // 获取最小长度值
        int minLen = Math.min(version1Array.length, version2Array.length);
        int diff = 0;
        // 循环判断每位的大小
        while (index < minLen
                && (diff = Integer.parseInt(version1Array[index]) - Integer.parseInt(version2Array[index])) == 0) {
            index++;
        }
        if (diff == 0) {
            // 如果位数不一致，比较多余位数
            for (int i = index; i < version1Array.length; i++) {
                if (Integer.parseInt(version1Array[i]) > 0) {
                    return true;
                }
            }

            for (int i = index; i < version2Array.length; i++) {
                if (Integer.parseInt(version2Array[i]) > 0) {
                    return false;
                }
            }
            return false;
        } else {
            return diff > 0 ? true : false;
        }
    }

    public static String shortWord(String str, int length) {
        String cutStr = "";
        if (!"".equals(str) && str != null) {
            if (str.length() <= length) {
                cutStr = str;
            } else {
                cutStr = str.substring(0, length);
            }
        }
        return cutStr;
    }

    public static double percentToPoint(String percent) {
        double result = 0;
        try {
            if (isNotBlank(percent)) {
                percent = percent.substring(0, percent.indexOf("%"));
                result = CommonUtils.parseDoubleData(percent) / 100;
            }
        } catch (Exception e) {
        }
        return result;
    }

    public static String myPercent(int y, int z) {
        // 接受百分比的值
        String baifenbi = "";
        double fen = 0.0;
        if (z == 0) {
            baifenbi = "0";
        } else {
            if (y == 0) {
                baifenbi = "0";
            } else {
                double baiy = y * 1.0;
                double baiz = z * 1.0;
                fen = baiy / baiz;
                if (fen > 1) {
                    fen = 1;
                }
            }
        }
        return formatDouble(fen);
    }

    public static String myPercent(double y, double z) {
        // 接受百分比的值
        String baifenbi = "";
        double fen = 0.0;
        if (z == 0) {
            baifenbi = "0";
        } else {
            if (y == 0) {
                baifenbi = "0";
            } else {
                double baiy = y * 1.0;
                double baiz = z * 1.0;
                fen = baiy / baiz;
                if (fen > 1) {
                    fen = 1;
                }
            }
        }
        return formatDouble(fen);
    }

    /**
     * 检查手机号的是否正确
     *
     * @param mobile
     * @return
     */
    public static boolean checkMobile(String mobile) {
        boolean result = false;
        if (CommonUtils.isNotBlank(mobile) && Pattern.matches(strPhone, mobile)) {
            result = true;
        }
        return result;
    }

    /**
     * 检查电子邮箱的是否正确
     *
     * @param email
     * @return
     */
    public static String checkEmail(String email) {
        String msg = "";
        if (!Pattern.matches(strEmail, email)) {
            msg = "请输入正确的邮箱";
        }
        return msg;
    }

    /**
     * 检查电话 正确格式的是否正确
     *
     * @param tel
     * @return
     */
    public static String checkTel(String tel) {
        String msg = "";
        if (!Pattern.matches(strTel, tel)) {
            msg = "请输入正确的电话 号码";
        }
        return msg;
    }

    /**
     * 检查是否输入汉字
     *
     * @param chinese
     * @return
     */
    public static String checkChinese(String chinese) {
        String msg = "";
        if (!Pattern.matches(strChinese, chinese)) {
            msg = "请输入汉字";
        }
        return msg;
    }

    /**
     * 检查IP
     *
     * @param ip
     * @return
     */
    public static String checkIP(String ip) {
        String msg = "";
        if (!Pattern.matches(strIp, ip)) {
            msg = "请输入正确的IP";
        }
        return msg;
    }

    /**
     * 检查QQ
     *
     * @param qq
     * @return
     */
    public static String checkQQ(String qq) {
        String msg = "";
        if (!Pattern.matches(strQQ, qq)) {
            msg = "请输入正确的QQ号";
        }
        return msg;
    }

    /**
     * 检查身份证号码
     *
     * @param identityNum
     * @return
     */
    public static String checkId(String identityNum) {
        String msg = "";
        if (!Pattern.matches(strId, identityNum)) {
            msg = "请输入正确的身份证号码";
        }
        return msg;
    }

    /**
     * 检查邮编
     *
     * @param mail
     * @return
     */
    public static String checkMail(String mail) {
        String msg = "";
        if (!Pattern.matches(strMail, mail)) {
            msg = "请输入正确的邮编";
        }
        return msg;
    }

    public static String trimAllBlankChar(String input) {
        if (input == null) {
            return "";
        }

        return input.replace("\n", "").replace("\r", "").replace("\t", "").trim();
    }

    /**
     * convert input to String type.
     *
     * @param input
     * @return
     */
    public static String parseStringData(Object input) {
        return parseStringData(input, "");
    }

    /**
     * convert input to String type.
     *
     * @param input
     * @param defaultValue, when input is null or empty, defaultValue will be returned as
     *                      result.
     * @return
     */
    public static String parseStringData(Object input, String defaultValue) {
        String result = defaultValue;
        if (input != null && !"".equals(input)) {
            return input.toString();
        }
        return result;
    }

    /**
     * convert input to Double type.
     *
     * @param input
     * @return, if fail to convert , Double(0) will be returned.
     */
    public static Double parseDoubleData(Object input) {
        return parseDoubleData(input, new Double(0));
    }

    /**
     * convert input to Double type.
     *
     * @param input
     * @param defaultValue
     * @return, if fail to convert, defaultValue will be returned.
     */
    public static Double parseDoubleData(Object input, Double defaultValue) {
        Double result = defaultValue;
        if (input != null && !"".equals(input)) {
            try {
                result = Double.parseDouble(input.toString().trim());
            } catch (Exception ex) {
            }
        }
        return result;
    }

    public static Boolean parseBooleanData(Object input) {
        return parseBooleanData(input, false);
    }

    public static Boolean parseBooleanData(Object input, Boolean defaultValue) {
        Boolean dblValue = Boolean.parseBoolean(input.toString());
        if (dblValue == false) {
            return defaultValue;
        }
        return dblValue;
    }

    /**
     * convert input to Long type.
     *
     * @param input
     * @return, if fail to convert, Integer(0) will be returned.
     */
    public static Long parseLongData(Object input) {
        return parseLongData(input, null);
    }

    /**
     * convert input to Long type.
     *
     * @param input
     * @param defaultValue
     * @return, if fail to convert, defaultValue will be returned.
     */
    public static Long parseLongData(Object input, Long defaultValue) {
        Double defaultDblValue = null;
        if (defaultValue != null) {
            // do not use Integer.parseInt, it can not fix the input such as:
            // 10.00
            defaultDblValue = Double.parseDouble(defaultValue.toString());
        }
        Double dblValue = parseDoubleData(input, defaultDblValue);
        if (dblValue == null) {
            return null;

        }
        return dblValue.longValue();
    }

    /**
     * convert input to Integer type.
     *
     * @param input
     * @return, if fail to convert, Integer(0) will be returned.
     */
    public static Integer parseIntegerData(Object input) {
        return parseIntegerData(input, new Integer(0));
    }

    /**
     * convert input to Integer type.
     *
     * @param input
     * @param defaultValue
     * @return, if fail to convert, defaultValue will be returned.
     */
    public static Integer parseIntegerData(Object input, Integer defaultValue) {
        Double defaultDblValue = null;
        if (defaultValue != null) {
            defaultDblValue = Double.parseDouble(defaultValue.toString());
        }
        Double dblValue = parseDoubleData(input, defaultDblValue);
        if (dblValue == null) {
            return null;
        }

        return dblValue.intValue();
    }


    /**
     * convert input to Date type.
     *
     * @param input
     * @param dateFormat,  e.g.: yyyy-MM-dd
     * @param defaultValue
     * @return, if fail to convert, defaultValue will be returned.
     */
    public static Date parseDateData(Object input, String dateFormat, Date defaultValue) {
        Date result = defaultValue;
        if (input != null && !"".equals(input)) {
            try {
                SimpleDateFormat myDateFormat = new SimpleDateFormat(dateFormat);
                result = myDateFormat.parse(input.toString().trim());
            } catch (Exception ex) {
            }
        }
        return result;
    }

    /**
     * convert input to Timestamp type.
     *
     * @param input
     * @param dateFormat, e.g.: yyyy-MM-dd @return, if fail to convert, null will be
     *                    returned.
     */
    public static Timestamp parseTimestampData(Object input, String dateFormat) {
        return parseTimestampData(input, dateFormat, null);
    }


    /**
     * convert input to Timestamp type.
     *
     * @param input
     * @param dateFormat,  e.g.: yyyy-MM-dd
     * @param defaultValue
     * @return, if fail to convert, defaultValue will be returned.
     */
    public static Timestamp parseTimestampData(Object input, String dateFormat, Timestamp defaultValue) {
        Timestamp result = defaultValue;
        if (input != null && !"".equals(input)) {
            try {
                SimpleDateFormat myDateFormat = new SimpleDateFormat(dateFormat);
                long time = myDateFormat.parse(input.toString()).getTime();
                result = new Timestamp(time);
            } catch (Exception ex) {
            }
        }
        return result;
    }

    public static String fixedSqlParam(String input) {
        String result = "";
        if (input != null && !"".equals(input)) {
            result = input.trim().replaceAll("'", "''");
        }
        return result;
    }

    public static String genUUIDString() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    public static String checkMobileNum(String mobile) {
        String msg = "";
        if (!Pattern.matches(MOBILE_MATCHE, mobile)) {
            msg = "请输入正确的手机号";
        }
        return msg;
    }

    public static String converTimeString(Object input) {
        String timeStr = parseStringData(input, "");
        if (timeStr != null && !("").equals(timeStr)) {
            timeStr = timeStr.substring(0, 19);
        }
        return timeStr;
    }

    public static List<String> getDiffrent(List<String> list1, List<String> list2) {
        long st = System.nanoTime();
        Map<String, Integer> map = new HashMap<String, Integer>(list1.size() + list2.size());
        List<String> diff = new ArrayList<String>();
        for (String string : list1) {
            map.put(string, 1);
        }
        for (String string : list2) {
            Integer cc = map.get(string);
            if (cc != null) {
                map.put(string, ++cc);
                continue;
            }
            map.put(string, 1);
        }
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        return diff;
    }

    public static void writeResponse(HttpServletResponse response, String content) throws Exception {

        response.setCharacterEncoding("UTF-8");
        PrintWriter pw = response.getWriter();
        pw.write(content);
        pw.flush();
        pw.close();
    }

    /**
     * 格式化数字显示百分数 如33.33%
     */
    public static String formatDouble(double percent) {
        // 获取格式化对象
        NumberFormat nt = NumberFormat.getPercentInstance();
        // 设置百分数精确度2即保留两位小数
        nt.setMinimumFractionDigits(2);
        // 最后格式化并输出
        return nt.format(percent);

    }

    public static int getNextInt() {
        Random random = new Random();
        int x = random.nextInt(899999);
        int z = x + 100000;
        return z;
    }

    public static String accuracy(int num, int total, int scale) {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        // 可以设置精确几位小数
        df.setMaximumFractionDigits(scale);
        if (total == 0) {
            return df.format(0) + "%";
        }
        // 模式 例如四舍五入
        df.setRoundingMode(RoundingMode.HALF_UP);
        double accuracyNum = ((double) num / (double) total) * 100;
        return df.format(accuracyNum) + "%";
    }

    public static Double percent(int num, int total, int scale) {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        // 可以设置精确几位小数
        df.setMaximumFractionDigits(scale);
        if (total == 0) {
            return parseDoubleData(df.format(0));
        }
        // 模式 例如四舍五入
        df.setRoundingMode(RoundingMode.HALF_UP);
        double accuracyNum = ((double) num / (double) total) * 100;
        return parseDoubleData(df.format(accuracyNum));
    }

    public static BigDecimal minuteConvertSecond(BigDecimal minuteSecond) {
        String minuteStr = minuteSecond.toString();
        if (!minuteStr.contains(MINUTE_SPLIT)) {
            return null;
        }
        String minute = minuteSecond.toString().substring(0, minuteSecond.toString().indexOf(MINUTE_SPLIT));
        String second = minuteSecond.toString().substring(minuteSecond.toString().indexOf(MINUTE_SPLIT) + 1);
        BigDecimal score = new BigDecimal(minute).multiply(new BigDecimal(TIME_UNIT_BASE)).add(new BigDecimal(second));
        return score;
    }

    public static String secondToMinute(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0) {
            return "0′00″";
        } else {
            minute = time / TIME_UNIT_BASE;
            int timeCarry = TIME_UNIT_BASE;
            int intCarry = INT_UNIT_BASE;
            if (minute < timeCarry) {
                second = time % timeCarry;
                if (second < intCarry) {
                    timeStr = minute + MINUTE_UNIT + "0" + second + SECOND_UNIT;
                } else {
                    timeStr = minute + MINUTE_UNIT + second + SECOND_UNIT;
                }

            } else {
                hour = minute / timeCarry;
                minute = minute % intCarry;
                second = time - hour * TIME_UNIT_BASE*TIME_UNIT_BASE - minute * TIME_UNIT_BASE;
                if (second < intCarry) {
                    timeStr = hour + HOUR_UNIT + minute + MINUTE_UNIT + "0" + second + SECOND_UNIT;
                } else {
                    timeStr = hour + HOUR_UNIT + minute + MINUTE_UNIT + second + SECOND_UNIT;
                }
            }
        }
        return timeStr;
    }


    /**
     * 方法描述 隐藏字符串中间的字符串（使用*号），显示前四后四
     *
     * @param str
     * @return
     * @author yaomy
     * @date 2018年4月3日 上午10:37:00
     */
    public static String hideString(String str, int beforeLength, int afterLength) {
        if (isBlank(str)) {
            return str;
        }

        int length = str.length();
        //替换字符串，当前使用“*”
        String replaceSymbol = "*";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            if (i < beforeLength || i >= (length - afterLength)) {
                sb.append(str.charAt(i));
            } else {
                sb.append(replaceSymbol);
            }
        }

        return sb.toString();
    }

    public static void main(String[] args) {
//        String password=RandomUtil.randomString("0123456789!@#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",8);
//        System.out.println(password);
//        String passwordEncodeStr = DigestUtils.md5DigestAsHex(password.getBytes());
//        System.out.println(passwordEncodeStr);
//        String content = "123456";
//
//        byte[] key ="bht_team".getBytes(StandardCharsets.UTF_8);
//
//        SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DES, key);
////
//////加密
////        byte[] encrypt = des.encrypt(content);
//////解密
////        byte[] decrypt = des.decrypt(encrypt);
//
////加密为16进制字符串（Hex表示）
//        String encryptHex = des.encryptHex(content);
////解密为字符串
//        String decryptStr = des.decryptStr(encryptHex);
//        System.out.println(encryptHex);
//        System.out.println(decryptStr);
//        boolean isMatch = ReUtil.isMatch(CommonUtils.POLAR_MATCHE, "90F76A21");
//        System.out.println(isMatch);
//        System.out.println(RandomUtil.randomInt(4,8));
        System.out.println(Long.parseLong("20230321225954737"));
    }

}
